package springsecurity.authentication;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.RequestMatcher;
import springsecurity.config.AuthConfig;
import springsecurity.utlis.AuthCache;
import springsecurity.dao.AuthConfigAttribute;
import springsecurity.dao.enums.AuthorityConstants;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @User: c.c
 * @Date: 2022/6/14
 * @Time: 11:17
 * @Description:  根据访问地址url 判断哪些需要登录后才能访问，哪些可以直接访问,并把值设置回Collection里方便 CustomAccessDecisionManager.decide(authentication) 里的authentication参数调用
 * 判定请求所需权限信息
 */

public class CustumerMetaDataSourcr implements FilterInvocationSecurityMetadataSource {

    private final AuthConfig authConfig;

    public CustumerMetaDataSourcr(AuthConfig authConfig) {
        this.authConfig = authConfig;
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        HttpServletRequest req = ((FilterInvocation) o).getHttpRequest();

        //从缓存里取的权限id （第一遍为空，因为没put）
        String matcher = AuthCache.getInstance().matcher(req.getMethod(), req.getRequestURI());

        //获取不需要 认证 就能直接访问的
        List<RequestMatcher> ignore_matchers = authConfig.getIGNORE_MATCHERS();
        for (RequestMatcher ignore_matcher : ignore_matchers) {
            if (ignore_matcher.matches(req)){
                System.err.println(req.getRequestURI()+"不需要登录");
                return Collections.singletonList(new AuthConfigAttribute(AuthorityConstants.PERMIT_ALL,matcher));
            }
        }
        //需要需要认证 即登录 才能访问 的
        for (RequestMatcher shareMatcher : authConfig.getLOGIN_SHARE_MATCHERS()) {
            if (shareMatcher.matches(req)) {
                System.out.println(req.getRequestURI()+"需要登录");
                return Collections.singletonList(new AuthConfigAttribute(AuthorityConstants.AUTHENTICATED, matcher));
            }
        }
        return Collections.singletonList(new AuthConfigAttribute(AuthorityConstants.NON_AUTH, null));
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return Collections.emptyList();
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return  FilterInvocation.class.isAssignableFrom(aClass);
    }
}
